package com.sunlands.deskmate.message.handler.dispatcher.impl;

import com.sunlands.deskmate.channel.ChannelInfo;
import com.sunlands.deskmate.channel.ChannelManager;
import com.sunlands.deskmate.message.entity.Messages;
import com.sunlands.deskmate.message.handler.dispatcher.Dispatcher;
import com.sunlands.deskmate.message.handler.storager.unsync.UnsyncMessageStorager;
import com.sunlands.deskmate.utils.IdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMapCache;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Objects;
import static com.sunlands.deskmate.config.RabbitMqConfig.EVENT_EXCHANGE_LOOKUP;

/**
 * 只发送给toId的人
 */
@Slf4j
@Component
public class OnePersonSocketMessageDispatcher implements Dispatcher {

    @Autowired
    private UnsyncMessageStorager unsyncMessageStorager;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void dispatcher(Messages messages) {

        RMapCache<String, ChannelInfo> redisChannelStore = ChannelManager.getRedisChannelStore();
        if(Objects.isNull(messages.getRealToId())){
            messages.setRealToId(Long.parseLong(messages.getToId()));
        }

        Long oldAckId = messages.getAckId();
        messages.setAckId(IdGenerator.id());
        log.info("1.2 防止消息乱序，将消息进行转换 重新生成ackId oldAckId = {} newAckId = {}", oldAckId, messages.getAckId());

        //给接受方发送消息
        if (Objects.nonNull(messages.getRealToId())) {
//            messages.setAckId(IdGenerator.id());
            ChannelInfo channelInfo = new ChannelInfo(messages.getRealToId());
            ChannelInfo info = redisChannelStore.get(channelInfo.getSessionKey());

            //如果通道为空，切消息类型为NOTICE_EVENT，直接抛掉
            if(Objects.isNull(info) ){
                log.info("通道为空消息直接抛掉，messages = {}", messages);
                return;
            }

            boolean success = unsyncMessageStorager.add(channelInfo.getSessionKey(), messages, messages.getAckId());
            if (success) {
                //通道信息为空的话，不通知发送消息，再次连上通道后会重新发送
                if(Objects.isNull(info)){
                    log.error("发送方redis channel为空，出现异常 messages = {}", messages);
                    return;
                }
                log.info("2、发送给个人的单向消息 msgEntity = {},",messages);
                rabbitTemplate.convertAndSend(EVENT_EXCHANGE_LOOKUP, info.getWorkId().toString(), messages);
            }
        }

    }
}
